package baiqitun.stupro.security.service.impl;

import baiqitun.stupro.common.exception.enums.support.ExistedExceptionEnum;
import baiqitun.stupro.common.exception.enums.support.NotFoundExceptionEnum;
import baiqitun.stupro.common.exception.support.NotFoundException;
import baiqitun.stupro.common.exception.support.RelationExistedException;
import baiqitun.stupro.common.service.support.MyServiceImpl;
import baiqitun.stupro.common.util.DateTimeUtil;
import baiqitun.stupro.security.entity.SysDepart;
import baiqitun.stupro.security.entity.SysDepartUser;
import baiqitun.stupro.security.entity.SysUser;
import baiqitun.stupro.security.mapper.SysDepartUserMapper;
import baiqitun.stupro.security.service.SysDepartService;
import baiqitun.stupro.security.service.SysDepartUserService;
import baiqitun.stupro.security.service.SysUserService;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;

import java.time.LocalDateTime;
import java.util.LinkedList;
import java.util.List;

/**
 * <p>
 * 部门用户表 服务实现类
 * </p>
 *
 * @author kedaji
 * @since 2020-03-25
 */
@Service
public class SysDepartUserServiceImpl extends MyServiceImpl<SysDepartUserMapper, SysDepartUser> implements SysDepartUserService{
    @Autowired
    private SysUserService sysUserService;
    @Autowired
    private SysDepartService sysDepartService;

    @CachePut("departUser")
    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean save(@Validated() SysDepartUser sysDepartUser){
        checkRelationExisted(sysDepartUser.getUserId(), sysDepartUser.getDepartId());
        return super.save(sysDepartUser);
    }

    @Transactional(rollbackFor = Exception.class)
    @CachePut("departUser")
    @Override
    public void saveUserToDepart(@Validated() SysUser user, String departId) {
        sysUserService.save(user);
        SysDepartUser relation = new SysDepartUser();
        relation.setUserId(user.getId()).setDepartId(departId).setCreateBy(user.getCreateBy());
        save(relation);
    }

    @Transactional(readOnly = true, rollbackFor = Exception.class)
    @Override
    public List<SysDepart> listDepartForUser(String userId) {
        SysDepartUser queryDepartUser = new SysDepartUser();
        queryDepartUser.setUserId(userId);
        List<SysDepartUser> relations = list(new QueryWrapper<>(queryDepartUser));
        List<SysDepart> departs = new LinkedList<>();
        for (SysDepartUser relation : relations){
            SysDepart depart = sysDepartService.getById(relation);
            departs.add(depart);
        }
        return departs;
    }

    @Transactional(readOnly = true, rollbackFor = Exception.class)
    @Override
    public List<SysUser> listUserForDepartOfYear(String departId, Integer year) {
        SysDepartUser queryDepartUser = new SysDepartUser();
        LocalDateTime firstDateTimeOfYear = DateTimeUtil.firstDateTimeOfYear(year);
        LocalDateTime lastDateTimeOfYear = DateTimeUtil.lastDateTimeOfYear(year);
        queryDepartUser.setDepartId(departId);
        List<SysDepartUser> relations = list(new QueryWrapper<>(queryDepartUser).between("create_datetime", firstDateTimeOfYear, lastDateTimeOfYear));
        List<SysUser> users = new LinkedList<>();
        for (SysDepartUser tmpRelation: relations){
            SysUser user = sysUserService.getById(tmpRelation.getUserId());
            users.add(user);
        }
        return users;
    }

    private void checkRelationExisted(String userId, String departId){
        sysUserService.checkEnabled(userId);
        sysDepartService.checkNotFound(departId, new NotFoundException(NotFoundExceptionEnum.DEPART_NOT_FOUND));
        SysDepartUser queryDepartUser = new SysDepartUser();
        queryDepartUser.setUserId(userId).setDepartId(departId);
        int count = count(new QueryWrapper<>(queryDepartUser));
        if (count > 0){
            throw new RelationExistedException(ExistedExceptionEnum.DEPART_USER_RELATION_EXISTED).put(SysDepart.class,"id", userId).put(SysUser.class,"id", departId);
        }
    }
}
